package main

import (
	"context"
	"flag"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"local.public/innerpkg/dbtool"
	"local.public/innerpkg/logger"
	"local.public/innerpkg/pubconfig"
	"local.public/innerpkg/shutdown"
	"local.public/internal/appconfig"
	"local.public/internal/ginroutes"
	"local.public/internal/initdata"
	"local.public/utils"
	"log"
	"net/http"
	"os"
	"time"
)

// 构建版本信息
var (
	BuildVersion   = ""
	GitCommitInfo  = ""
	BuildGoVersion = ""
	BuildTime      = ""
)

// @title 公共库 local.public
// @version 1.0
// @description 供其它项目引用的公共对象方法等
// @BasePath /
func main() {
	var fVersion bool
	var fDemo bool

	flag.BoolVar(&fVersion, "v", false, "version")
	flag.BoolVar(&fDemo, "d", false, "demo")
	flag.Parse()
	// flag v 版本信息
	if fVersion {
		fmt.Printf("Version      : %s\n", BuildVersion)
		fmt.Printf("GitCommitInfo: %s\n", GitCommitInfo)
		fmt.Printf("Go Version   : %s\n", BuildGoVersion)
		fmt.Printf("Build Time   : %s\n", BuildTime)
		return
	}

	if fDemo {
		fmt.Printf("第几周      : %s\n", utils.WeekNoByDate(time.Now()))
		dt, _ := time.Parse("2006-01-02", "2024-01-02")
		fmt.Printf("第几周      : %s\n", utils.WeekNoByDate(dt))

		fmt.Println("httpsDomain:" + pubconfig.GetConfig().WebServer.WebsiteDomain)
		return
	}

	if len(os.Args) > 1 && os.Args[1] == "init" {
		dsnBusiness := pubconfig.GetConfig().Storage.BusinessDbpath
		if err := dbtool.InitBusinessDB(dsnBusiness); err != nil {
			logger.Error("CRM Business 数据库连接失败")
			return
		}
		dsnLogs := pubconfig.GetConfig().Storage.LogsDbpath
		if err := dbtool.InitBusinessDB(dsnLogs); err != nil {
			logger.Error("CRM Logs 数据库连接失败")
			return
		}
		initdata.InitData()
		return
	}

	// 连接mysql
	dsnBusiness := pubconfig.GetConfig().Storage.BusinessDbpath
	if err := dbtool.InitBusinessDB(dsnBusiness); err != nil {
		logger.Error("CRM Business 数据库连接失败")
		os.Exit(1)
	}
	dsnLogs := pubconfig.GetConfig().Storage.LogsDbpath
	if err := dbtool.InitLogsDB(dsnLogs); err != nil {
		logger.Error("CRM Logs 数据库连接失败")
		os.Exit(1)
	}

	//// 连接redis
	//redisAddr := pubconfig.GetConfig().Redis.Addr
	//redisDB := pubconfig.GetConfig().Redis.DB
	//if err := redistool.InitRedisCache(redisAddr, redisDB); err != nil {
	//	logger.Error("连接Redis失败")
	//	os.Exit(1)
	//}
	//// 连接nats
	//natsUrl := pubconfig.GetConfig().Nats.Addr
	//if err := mqtool.InitMqConn(natsUrl); err != nil {
	//	os.Exit(1)
	//}
	//// 连接mqtt
	//strBrokerAddr := pubconfig.GetConfig().Mqtt.Addr
	//strClientId := appconfig.GetConfig().Mqtt.ClientId
	//if err := mqtttool.InitMqttConn(strBrokerAddr, strClientId, shin.MqttMsgHandler); err != nil {
	//	logger.Error("建立mqtt失败", err.Error())
	//	os.Exit(1)
	//}
	//if err := mqtttool.AddMqttSubscribe("workeradmin/report/#"); err != nil {
	//	logger.Error("mqtt增加subject失败", err.Error())
	//	os.Exit(1)
	//}
	//创建和启动web服务(gin)
	gin.SetMode("debug")
	g := ginroutes.InitRouter() // 路由初始化
	srv := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", "0.0.0.0", appconfig.GetConfig().Listen.Port),
		Handler: g,
	}
	go func() {
		logger.Debug("开始启动", srv.Addr)
		err := srv.ListenAndServe()
		// 启动时候如果报错，并且错误不是关闭服务器，则打印日志并退出
		if err != nil && err != http.ErrServerClosed {
			log.Fatalf("服务启动失败，%s", err.Error())
		}
	}()

	// 优雅关闭
	shutdown.NewHook().Close(
		// 关闭 http server
		func() {
			logger.Debug("shutdown...,关闭 http server")
			ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
			defer cancel()

			if err := srv.Shutdown(ctx); err != nil {
				logger.Error("server shutdown err", zap.Error(err))
			}
		},
		//// 关闭 mqtt conn
		//func() {
		//	logger.Debug("shutdown...,关闭mqtt连接")
		//	mqtttool.CloseMqttConn()
		//},
		////// 关闭 mq conn
		//func() {
		//	logger.Debug("shutdown...,关闭 mq conn")
		//	mqtool.CloseMqConn()
		//},
		//// 关闭 redis cache
		//func() {
		//	logger.Debug("shutdown...,关闭 redis")
		//	redistool.CloseRedisCache()
		//},
		// 关闭 mysql db
		func() {
			logger.Debug("shutdown...,关闭 mysql base db")
			dbtool.CloseBusinessDB()
			dbtool.CloseLogsDB()
		},
	)
}
